package com.hspedu.hspliving.commodity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hspedu.common.utils.R;
import com.hspedu.hspliving.commodity.dao.AttrAttrgroupRelationDao;
import com.hspedu.hspliving.commodity.dao.AttrgroupDao;
import com.hspedu.hspliving.commodity.entity.AttrAttrgroupRelationEntity;
import com.hspedu.hspliving.commodity.entity.AttrgroupEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hspedu.common.utils.PageUtils;
import com.hspedu.common.utils.Query;

import com.hspedu.hspliving.commodity.dao.AttrDao;
import com.hspedu.hspliving.commodity.entity.AttrEntity;
import com.hspedu.hspliving.commodity.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Resource
    private AttrgroupDao attrgroupDao;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 保存商品属性信息，同时保存商品属性和他的商品属性组关联关系
     * @@Transactional 开启事务
     * @param attr
     */
    @Transactional
    @Override
    public void saveAttrAndRelation(AttrEntity attr) {
        //1.先保存基本属性数据
        this.save(attr);
        //上面方法执行后attr对象 AttrId属性会出现自增长数字
        //2.保存属性组与基本属性数据
        int insert = 0;
        if (attr.getAttrType() == 1
                && attr.getAttrGroupId() != null
                && attr.getAttrId() != null){
            //基本属性且属性id和属性组id不为空
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                    new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            insert = attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
        }
    }

    /**
     * 修改基本属性数据->联动基本属性与属性组表
     * @param attr
     * @return
     */
    @Transactional
    public void updateAttrAndRelation(AttrEntity attr) {
        //1.修改基本属性表数据
        if (attr == null) {
            return;
        }
        this.updateById(attr);
        //2.对基本属性和属性组关系表修改
        int update = 0;
        if (attr.getAttrType() == 1
                && attr.getAttrGroupId() != null
                && attr.getAttrId() != null) {
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                    new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
            update = attrAttrgroupRelationDao.update(attrAttrgroupRelationEntity
                    , new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq(AttrAttrgroupRelationEntity::getAttrId
                                    , attrAttrgroupRelationEntity.getAttrId()));
        }
    }

    /**
     * 删除基本属性和关联信息
     * @param list
     */
    @Override
    @Transactional
    public void delAttrAndRelation(List<Long> list){
        //1.删除基本属性表
        this.removeByIds(list);
        //2.删除关联信息
        //list中为attrId集合
        for (Long attrId : list) {
            LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper =
                    new LambdaQueryWrapper<>();
            wrapper.eq(AttrAttrgroupRelationEntity::getAttrId,attrId.intValue());
            attrAttrgroupRelationDao.delete(wrapper);
        }
    }

    /**
     * 根据分类id,和基本属性名进行分页查询
     * @param params
     * @param categoryId
     * @return
     */
    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long categoryId) {
        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();
        //查询基本属性
        queryWrapper.eq(AttrEntity::getAttrType,1);
        //携带categoryId
        if (categoryId != 0){
            //如果为0, 表示不将categoryId 作为查询条件
            queryWrapper.eq(AttrEntity::getCategoryId,categoryId);
        }
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)){
            //带有独立括号
            queryWrapper.and((wrapper) ->{
                wrapper.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params)
                , queryWrapper);
        return new PageUtils(page);
    }

    /**
     * 销售属性分页查询
     * @param params
     * @param categoryId
     * @return
     */
    @Override
    public PageUtils querySaleAttrPage(Map<String, Object> params, Long categoryId) {
        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();
        //查询销售属性
        queryWrapper.eq(AttrEntity::getAttrType,0);
        //携带categoryId
        if (categoryId != 0){
            //如果为0, 表示不将categoryId 作为查询条件
            queryWrapper.eq(AttrEntity::getCategoryId,categoryId);
        }
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)){
            //带有独立括号
            queryWrapper.and((wrapper) ->{
                wrapper.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params)
                , queryWrapper);
        return new PageUtils(page);
    }

    /**
     * 查询基本属性id对应属性组信息
     * @param attrId
     * @return
     */
    @Override
    public R queryAttrGroupNameByBaseAttrId(String attrId) {
        if (StringUtils.isEmpty(attrId)){
            return R.error();
        }
        //获取属性id对应属性关联实体
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrAttrgroupRelationEntity::getAttrId,attrId);
        AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                attrAttrgroupRelationDao.selectOne(wrapper);
        //属性组id
        Long attrGroupId = attrAttrgroupRelationEntity.getAttrGroupId();
        AttrgroupEntity attrgroupEntity = attrgroupDao.selectById(attrGroupId);
        return R.ok().put("data",attrgroupEntity);
    }


    /**
     * 根据属性组id 返回关联的 基本属性
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        if (attrgroupId == null){
            return null;
        }
        //1.根据传入 attrgroupId 获取到符合的属性组信息
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper =
                new LambdaQueryWrapper<>();
        wrapper.eq(AttrAttrgroupRelationEntity::getAttrGroupId,attrgroupId);
        List<AttrAttrgroupRelationEntity> entities =
                attrAttrgroupRelationDao.selectList(wrapper);
        //2.遍历得到 基本属性 id -> 基本属性id集合
        List<Long> attrIds = entities.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        //3.通过 attrIds 获取基本属性信息
        if (attrIds == null || attrIds.size() == 0){//无效的属性组id
            return null;
        }
        Collection<AttrEntity> attrEntities = this.listByIds(attrIds);
        return  (List<AttrEntity>) attrEntities;
    }


    /**
     * 批量删除属性组 和 属性关联关系
     * @param attrAttrgroupRelationEntities
     */
    @Override
    public void deleteRelation(AttrAttrgroupRelationEntity[] attrAttrgroupRelationEntities) {
        //属性组批量删除
        attrAttrgroupRelationDao.deleteBatchRelation(
                Arrays.asList(attrAttrgroupRelationEntities));
    }

    /**
     * 获取某个分组可以关联的属性
     1. 如果某个属性被某个属性分组关联了，就不能再关联
     2. 某个属性分组能够关联的属性，必须是同一个分类
     * @param params
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getAllowRelationAttr(Map<String, Object> params, Long attrgroupId) {
        if (attrgroupId == null){
            return null;
        }
        //1.通过属性组id 得到对应的category_id
        AttrgroupEntity attrgroupEntity = attrgroupDao.selectById(attrgroupId);
        if (attrgroupEntity == null){
            return null;
        }

        //2.通过分类id 得到对应的基本属性
        Long categoryId = attrgroupEntity.getCategoryId();
        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AttrEntity::getCategoryId,categoryId);
        queryWrapper.eq(AttrEntity::getAttrType,1);//基本属性

        //--------- 增加需求，排除已经关联的基本属性
        //2.1 先得到当前分类id 对应的所有分组
        List<AttrgroupEntity> group = attrgroupDao.selectList(
                new LambdaQueryWrapper<AttrgroupEntity>().
                        eq(AttrgroupEntity::getCategoryId, categoryId));
        //2.1 得到所有属性组id
        List<Long> attrGroupIds = group.stream().map((item) -> {
            return item.getId();
        }).collect(Collectors.toList());
        //2.2 在到commodity_attr_attrgroup_relation 中，检索与attrGroupIds 关联的基本属性
        List<AttrAttrgroupRelationEntity> attrs =  attrAttrgroupRelationDao.selectList(
                new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                        .in(AttrAttrgroupRelationEntity::getAttrGroupId,attrGroupIds));
//        List<AttrAttrgroupRelationEntity> attrs =  attrAttrgroupRelationDao.selectList(
//                new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
//                        .eq(AttrAttrgroupRelationEntity::getAttrGroupId,attrgroupId));
        //2.3 收集上面对应的 基本属性id attr_id
        List<Long> baseAttrIds = attrs.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        //2.4 增加条件排序上面 集合
        if (baseAttrIds != null && baseAttrIds.size() != 0){
            //携带 去掉已经关联的基本属性id
            queryWrapper.notIn(AttrEntity::getAttrId,baseAttrIds);
        }
        //3.条件检索条件
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)){
            queryWrapper.and((w)->{//id 或 name
                w.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key);
            });
        }
        //分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params)
                , queryWrapper);
        return new PageUtils(page);
    }

}
